/*
 * io.h
 *
 *  Created on: Mar 31, 2012
 *      Author: lin
 */

#ifndef IO_H_
#define IO_H_

#include <stdio.h>
#include <errno.h>
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>

#include "collection/link_list.h"

int io_fread_unlocked(FILE *fp, size_t size, size_t n, void *buf,
        size_t *readed);

int io_fwrite_unlocked(FILE *fp, size_t size, size_t n, const void *buf);

int io_read(int fd, void *buf, size_t n, size_t *readed);

int io_write(int fd, const void *buf, size_t n);

int io_pread(int fd, void *buf, size_t n, int64_t off, size_t *readed);

int io_pwrite(int fd, const void *buf, size_t n, int64_t off);

typedef int (*io_file_list_fliter_proc)(const struct dirent* entry);
int io_file_list_fliter_sysdot(const struct dirent* entry);
int io_file_list(const char *dir, char *** list, int *num,
        io_file_list_fliter_proc filter);

static inline int io_file_exist(const char *file, int *rt) {
    return access(file, F_OK) == 0;
}

static inline int io_file_type(const char *path, int *type) {
    struct stat buf;
    if (stat(path, &buf) != 0) {
        return errno;
    }
    *type = buf.st_mode;
    return 0;
}
static inline int io_is_file(const char *path, int *rt) {
    int type;
    int no = io_file_type(path, &type);
    return no ? no : (*rt = S_ISREG(type), 0);
}
static inline int io_is_dir(const char *path, int *rt) {
    int type;
    int no = io_file_type(path, &type);
    return no ? no : (*rt = S_ISDIR(type), 0);
}

static inline int io_file_delete(const char *file) {
    return unlink(file) ? errno : 0;
}

static inline int io_mkdir(const char *dir) {
    return mkdir(dir, 0755) ? errno : 0;
}

static inline int io_rmdir(const char *dir) {
    return rmdir(dir) ? errno : 0;
}

int io_rmdir_r(const char *dir);

#endif /* IO_H_ */
